using Api.Model.BaseModel;
using Api.Model.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace Api.Model
{
    public class ApiDbContext : DbContext
    {
        public virtual DbSet<Article> Article { get; set; }
        public virtual DbSet<ArticleType> ArticleType { get; set; }
        public virtual DbSet<Tag> Tag { get; set; }
        public virtual DbSet<TagArticle> TagArticle { get; set; }
        public ApiDbContext(DbContextOptions<ApiDbContext> options)
            : base(options)
        {

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Article>(x =>
            {
                x.HasKey(x => x.Id);
                x.Property(x => x.Url).HasColumnType("varchar(30)").HasMaxLength(30);
                x.Property(x => x.Digest).HasColumnType("varchar(200)").HasMaxLength(200);
                x.Property(x => x.Title).HasColumnType("varchar(30)").HasMaxLength(30);
                x.HasMany(x => x.TagArticles).WithOne(x => x.Article);
                x.HasOne(x => x.ArticleType).WithMany(x => x.Articles).HasForeignKey(x => x.ArticleTypeId).IsRequired();
            });
            modelBuilder.Entity<ArticleType>(x =>
            {
                x.HasKey(x => x.Id);
                x.HasMany(x => x.Articles).WithOne(x => x.ArticleType).IsRequired();
                x.Property(x => x.Image).HasColumnType("varchar(30)").HasMaxLength(30);
                x.Property(x => x.Name).HasColumnType("varchar(30)").HasMaxLength(30);
            });
            modelBuilder.Entity<Tag>(x =>
            {
                x.HasKey(x => x.Id);
                x.HasMany(x => x.TagArticles).WithOne(x => x.Tag);
                x.Property(x => x.Name).HasColumnType("varchar(30)").HasMaxLength(30);
            });
            modelBuilder.Entity<TagArticle>(x =>
            {
                x.HasKey(x => new { x.ArticleId, x.TagId });
                x.HasOne(x => x.Tag).WithMany(x => x.TagArticles).HasForeignKey(x => x.TagId).IsRequired();
                x.HasOne(x => x.Article).WithMany(x => x.TagArticles).HasForeignKey(x => x.ArticleId).IsRequired();
            });
            var entityTypeList = modelBuilder.Model.GetEntityTypes().Where(x => typeof(IAudit).IsAssignableFrom(x.ClrType));
            foreach (var entityType in entityTypeList)
            {
                var parameter = Expression.Parameter(entityType.ClrType);

                var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));

                var isDeletedProperty = Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted"));

                BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty, Expression.Constant(false));

                var lambdaExpression = Expression.Lambda(compareExpression, parameter);

                modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambdaExpression);

            }
            base.OnModelCreating(modelBuilder);
        }
    }
}
